package com.neepu.util.annotation;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.neepu.pojo.LogInfo;
import com.neepu.pojo.User;
import com.neepu.service.LogInfoService;
import com.neepu.util.common.Constants;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * 操作日志类
 *
 */

@Aspect
@Component
public class ArchivesLogAspect {

    @Autowired
    private LogInfoService loginfoService;

    private static final Logger logger = LoggerFactory.getLogger(ArchivesLog.class);

    @Pointcut("@annotation(com.neepu.util.annotation.ArchivesLog)")
    public void controllerAspect() {
        System.out.println("切入点...");
    }

    @Pointcut("@annotation(com.neepu.util.annotation.BeforeLog)")
    public void exitAspect(){
        System.out.println("切入点...");
    }


    @Before("exitAspect()")
    public void before(JoinPoint joinPoint) throws ClassNotFoundException {
        // 用户学号
        String userId = getUSerMsg().getUserID();
//        用户姓名
        String userName = getUSerMsg().getUserName();
        // 操作说明
        String operteContent = "退出系统";

        LogInfo logInfo = new LogInfo();
        logInfo.setUserID(userId);
        logInfo.setUserName(userName);
        logInfo.setOperationShow(operteContent);
        loginfoService.insertLog(logInfo);
    }

    /**
     * 方法调用后触发 , 记录正常操作
     *
     * @param joinPoint
     * @throws ClassNotFoundException
     */
    @AfterReturning("controllerAspect()")
    public  void after(JoinPoint joinPoint) throws NullPointerException {
        // 用户学号
        String userId = getUSerMsg().getUserID();
//        用户姓名
        String userName = getUSerMsg().getUserName();
        // 操作说明
        String operteContent = null;
        try {
            operteContent = getMethodDesc(joinPoint).getOperationShow();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        LogInfo logInfo = new LogInfo();
        logInfo.setUserID(userId);
        logInfo.setUserName(userName);
        logInfo.setOperationShow(operteContent);
        loginfoService.insertLog(logInfo);
    }

    /**
     *  发生异常，走此方法
     * @param joinPoint
     * @param e
     */
    @AfterThrowing(pointcut = "controllerAspect()", throwing = "e")
    public void AfterThrowing(JoinPoint joinPoint, Throwable e) {
        try {
            // 用户id
            String userId = getUSerMsg().getUserID();
            String userName = getUSerMsg().getUserName();
            String operteContent = getMethodDesc(joinPoint).getOperationShow();
            LogInfo logInfo = new LogInfo();
            String exMsg = e.getCause().toString();
            if (exMsg != null) {
                logInfo.setUserID(userId);
                logInfo.setUserName(userName);
                logInfo.setOperationShow(operteContent);
                logInfo.setExceptionMessage(exMsg);
                loginfoService.insertLog(logInfo);
            }
        } catch (Exception e1) {
            logger.error(e1.getMessage());
        }
    }

    /**
     * 获取 注解中对方法的描述
     *
     * @return
     * @throws ClassNotFoundException
     */
    public static LogInfo getMethodDesc(JoinPoint joinPoint) throws ClassNotFoundException {
        String targetName = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        Object[] arguments = joinPoint.getArgs();
        Class targetClass = Class.forName(targetName);
        Method[] methods = targetClass.getMethods();
        String operteContent = "";
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                Class[] clazzs = method.getParameterTypes();
                if (clazzs.length == arguments.length) {
                   // 操作说明
                    operteContent = method.getAnnotation(ArchivesLog.class).operteContent();
                    break;
                }
            }
        }
        LogInfo logInfo = new LogInfo();
        logInfo.setOperationShow(operteContent);
        return logInfo;
    }

    /**
     * 得到用户信息
     *
     * @return
     */
    public static User getUSerMsg() {
        HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        // 获取session
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute(Constants.USER_SESSION);
        return user;
    }

}
